import {NamedObject} from './named_object'
import {CToolManager} from './ctool_manager'
import Kline from './kline'



export class DataSource extends NamedObject {

    constructor(name) {
        super(name);
    }

    getUpdateMode() {
        return this._updateMode;
    }

    setUpdateMode(mode) {
        this._updateMode = mode;
    }

    getCacheSize() {
        return 0;
    }

    getDataCount() {
        return 0;
    }

    getDataAt(index) {
        return this._dataItems[index];
    }

}
DataSource.UpdateMode = {
    DoNothing: 0,
    Refresh: 1,
    Update: 2,
    Append: 3
};


export class MainDataSource extends DataSource {

    constructor(name) {
        super(name);
        this._erasedCount = 0;
        this._dataItems = [];
        this._dataObjects = {};
        this._decimalDigits = 0;
        this.toolManager = new CToolManager(name);
    }

    getCacheSize() {
        return this._dataItems.length;
    }

    getDataCount() {
        return this._dataItems.length;
    }

    getUpdatedCount() {
        return this._updatedCount;
    }

    getAppendedCount() {
        return this._appendedCount;
    }

    getErasedCount() {
        return this._erasedCount;
    }

    getDecimalDigits() {
        return this._decimalDigits;
    }

    calcDecimalDigits(v) {
        let str = "" + v;
        let i = str.indexOf('.');
        if (i < 0) {
            return 0;
        }
        return (str.length - 1) - i;
    }

    getLastDate() {
        let count = this.getDataCount();
        if (count < 1) {
            return -1;
        }
        return this.getDataAt(count - 1).date;
    }

    getDataAt(index) {
        return this._dataItems[index];
    }

    getDataItemToObject(e) {
        
      return {
        date: e[0],
        open: e[1],
        high: e[2],
        low: e[3],
        close: e[4],
        volume: e[5]
      }
    }

    checkDataIsSame(lastItem, e) {
      return lastItem.open === e[1] &&
      lastItem.high === e[2] &&
      lastItem.low === e[3] &&
      lastItem.close === e[4] &&
      lastItem.volume === e[5]
    }

    setDataRefresh(data) {
      this.setUpdateMode(DataSource.UpdateMode.Refresh);
        this._dataItems = [];
        this._dataObjects = {};
        let d, n, e, i, cnt = data.length;
        for (i = 0; i < cnt; i++) {
            e = data[i];
            for (n = 1; n <= 4; n++) {
                d = this.calcDecimalDigits(e[n]);
                if (this._decimalDigits < d)
                    this._decimalDigits = d;
            }
            this.pushDataItemToList(e)
        }
    }

    pushDataItemToList(e) {
      let _dataItem = this.getDataItemToObject(e)
      this._dataObjects[e[0]] = {
        data: _dataItem,
        index: this._dataItems.length
      };
      this._dataItems.push(_dataItem);
    }

    update(data) {
        this._updatedCount = 0;
        this._appendedCount = 0;
        this._erasedCount = 0;
        let len = this._dataItems.length;
        if (len > 0) {
            let lastIndex = len - 1;
            let lastItem = this._dataItems[lastIndex];
            let t, e, i, cnt = data.length, currnetIndex = -1;
            for (i = 0; i < cnt; i++) {
                e = data[i];
                /**
                 * 修改部分代码开始
                 */
                t = this._dataObjects[e[0]];
                // 判断当前数据是否已存在列表中，如果一样就不需要处理
                if (t && e[0] === t.data.date)  {
                  if (this.checkDataIsSame(t.data, e)) {
                    this.setUpdateMode(DataSource.UpdateMode.DoNothing);
                    // 如果始终都没有更新返回true
                    if (i === cnt - 1) {
                      return true;
                    }
                    currnetIndex = t.index
                    continue;
                  }
                }
                // 如果一开始都没数据一样则走刷新流程
                if (currnetIndex === -1) {
                  this.setDataRefresh(data)
                  return true;
                }
                // 如果只是最后一个数据不一样
                if (currnetIndex + 1 === lastIndex) {
                  this.setUpdateMode(DataSource.UpdateMode.Update);
                  let currentItem = this.getDataItemToObject(e);
                  this._dataItems[lastIndex] = currentItem;
                  // 更新数据位置信息
                  delete this._dataObjects[lastItem.date];
                  this._dataObjects[e[0]] = {
                    index: lastIndex,
                    data: currentItem
                  };
                  this._updatedCount++;
                  i++;
                  if (i < cnt) {
                    this.setUpdateMode(DataSource.UpdateMode.Append);
                    for (; i < cnt; i++, this._appendedCount++) {
                        e = data[i];
                        this.pushDataItemToList(e)
                    }
                  }
                  return true
                }
                // 中间开始数据不一样，直接刷新页面更新
                this.setDataRefresh(data)
                return true;
                /**
                 * 修改部分代码结束
                 */

                // // 如果是最后一个数据有变化
                // if (e[0] === lastItem.date) {
                //     // 如果数据值一样就不更新
                //     if (lastItem.open === e[1] &&
                //         lastItem.high === e[2] &&
                //         lastItem.low === e[3] &&
                //         lastItem.close === e[4] &&
                //         lastItem.volume === e[5]) {
                //         this.setUpdateMode(DataSource.UpdateMode.DoNothing);
                //     } else {
                //         // 如果数据值不一样就更新
                //         this.setUpdateMode(DataSource.UpdateMode.Update);
                //         this._dataItems[lastIndex] = {
                //             date: e[0],
                //             open: e[1],
                //             high: e[2],
                //             low: e[3],
                //             close: e[4],
                //             volume: e[5]
                //         };
                //         this._updatedCount++;
                //     }
                //     i++;
                //     // 如果数组后面还有数据就追加
                //     if (i < cnt) {
                //         this.setUpdateMode(DataSource.UpdateMode.Append);
                //         for (; i < cnt; i++, this._appendedCount++) {
                //             e = data[i];
                //             this._dataItems.push({
                //                 date: e[0],
                //                 open: e[1],
                //                 high: e[2],
                //                 low: e[3],
                //                 close: e[4],
                //                 volume: e[5]
                //             });
                //         }
                //     }
                //     return true;
                // }
            }
            // // 如果数据长度小于数据设置的最大长度则不更新（这个暂时没发现用处）
            // if (cnt < Kline.instance.limit) {
            //     this.setUpdateMode(DataSource.UpdateMode.DoNothing);
            //     return false;
            // }
        }
        this.setDataRefresh(data)
        return true;
    }

    select(id) {
        this.toolManager.selecedObject = id;
    }

    unselect() {
        this.toolManager.selecedObject = -1;
    }

    addToolObject(toolObject) {
        this.toolManager.addToolObject(toolObject);
    }

    delToolObject() {
        this.toolManager.delCurrentObject();
    }

    getToolObject(index) {
        return this.toolManager.getToolObject(index);
    }

    getToolObjectCount() {
        return this.toolManager.toolObjects.length;
    }

    getCurrentToolObject() {
        return this.toolManager.getCurrentObject();
    }

    getSelectToolObjcet() {
        return this.toolManager.getSelectedObject();
    }

    delSelectToolObject() {
        this.toolManager.delSelectedObject();
    }

}

